package xyz.lwm.lazycat.beans;

import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.function.Predicate;

/**
 * <h3>bean design 注册</h3>
 * <p>注册器获取方式</p>
 *
 * <p>1. 使用 {@link BeanDesignRegistryCustomizer} 获取</p>
 * <pre>{@code
 * @Bean
 * public class MyBeanDesignRegistryCustomizer implements BeanDesignRegistryCustomizer {
 *     private BeanDesignRegistry beanDesignRegistry;
 *     @Override
 *     public void customize(BeanDesignRegistry beanRegistry) {
 *         this.beanDesignRegistry = beanRegistry;
 *     }
 * }
 * }</pre>
 *
 * <p>2. 使用 {@link BeansCustomizer} 获取</p>
 * <pre>{@code
 * @Bean
 * public class MyBeansCustomizer implements BeansCustomizer {
 *     private BeanDesignRegistry beanDesignRegistry;
 *     @Override
 *     public void customize(BeanDesignRegistry registry, Beans beans) {
 *         this.beanDesignRegistry = registry;
 *     }
 * }
 * }</pre>
 *
 * <p>3. 使用 {@link xyz.lwm.lazycat.annotation.Inject}</p>
 * <pre>{@code
 * @Bean
 * public class MyService {
 *     @Inject
 *     private BeanDesignRegistry beanDesignRegistry;
 * }
 * }</pre>
 *
 * @author lwm
 */
public interface BeanDesignRegistry {

    /**
     * 判断某个 bean name 是否被注册
     *
     * @param beanName bean name
     * @return 是否被注册
     */
    boolean isRegistered(@NotNull String beanName);

    /**
     * 注销某个 bean name 的设计
     *
     * @param beanName bean name
     * @throws BeansException 注册失败
     */
    void unregister(@NotNull String beanName) throws BeansException;

    /**
     * 注册一个 bean design
     *
     * @param design design
     * @throws BeansException 注册失败
     */
    <T> void register(BeanDesign<T> design) throws BeansException;

    /**
     * 获取 design
     *
     * @param beanName bean name
     * @return design
     * @throws BeansException 获取失败
     */
    BeanDesign<?> getDesign(@NotNull String beanName) throws BeansException;

    /**
     * 获取 design 集合
     *
     * @param filter 过滤条件
     * @return design
     * @throws BeansException 获取失败
     */
    Map<String, BeanDesign<?>> getDesigns(@NotNull Predicate<BeanDesign<?>> filter) throws BeansException;

}
